/******************************************************************************* * Copyright (c) 2005, 2016 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation * Patrik Suzzi <psuzzi@gmail.com> - Bug 490700 *******************************************************************************/ package org.eclipse.ui.internal.wizards.preferences; import static org.eclipse.swt.events.SelectionListener.widgetSelectedAdapter; import java.io.File; import java.util.Arrays; import java.util.List; import java.util.Map; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.preferences.ConfigurationScope; import org.eclipse.core.runtime.preferences.IPreferenceFilter; import org.eclipse.core.runtime.preferences.InstanceScope; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.jface.dialogs.IDialogSettings; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.layout.LayoutConstants; import org.eclipse.jface.viewers.CheckboxTreeViewer; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.jface.wizard.WizardPage; import org.eclipse.osgi.util.NLS; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.graphics.Font; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Combo; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.FileDialog; import org.eclipse.swt.widgets.Group; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Text; import org.eclipse.swt.widgets.Widget; import org.eclipse.ui.dialogs.FilteredTree; import org.eclipse.ui.dialogs.IOverwriteQuery; import org.eclipse.ui.dialogs.PatternFilter; import org.eclipse.ui.internal.WorkbenchPlugin; import org.eclipse.ui.internal.preferences.PreferenceTransferElement; import org.eclipse.ui.internal.preferences.PreferenceTransferManager; import org.eclipse.ui.model.WorkbenchLabelProvider; /** * Base class for preference export/import pages. * * @since 3.1 */ public abstract class WizardPreferencesPage extends WizardPage implements Listener, IOverwriteQuery { // widgets protected Combo destinationNameField; private Button destinationBrowseButton; private Button overwriteExistingFilesCheckbox; protected FilteredTree transfersTree; protected Text descText; private Composite buttonComposite; private Button transferAllButton; private Group group; private CheckboxTreeViewer viewer; private Button selectAllButton; private Button deselectAllButton; // dialog store id constants private static final String STORE_DESTINATION_NAMES_ID = "WizardPreferencesExportPage1.STORE_DESTINATION_NAMES_ID";//$NON-NLS-1$ private static final String STORE_OVERWRITE_EXISTING_FILES_ID = "WizardPreferencesExportPage1.STORE_OVERWRITE_EXISTING_FILES_ID";//$NON-NLS-1$ private static final String TRANSFER_ALL_PREFERENCES_ID = "WizardPreferencesExportPage1.EXPORT_ALL_PREFERENCES_ID"; //$NON-NLS-1$ private static final String TRANSFER_PREFERENCES_NAMES_ID = "WizardPreferencesExportPage1.TRANSFER_PREFERENCES_NAMES_ID"; //$NON-NLS-1$ private PreferenceTransferElement[] transfers; private String currentMessage; private static final String STORE_DESTINATION_ID = null; protected static final int COMBO_HISTORY_LENGTH = 5; /** * @param pageName */ protected WizardPreferencesPage(String pageName) { super(pageName); } /** * Creates a new button with the given id. * <p> * The <code>Dialog</code> implementation of this framework method creates * a standard push button, registers for selection events including button * presses and registers default buttons with its shell. The button id is * stored as the buttons client data. Note that the parent's layout is * assumed to be a GridLayout and the number of columns in this layout is * incremented. Subclasses may override. * </p> * * @param parent * the parent composite * @param id * the id of the button (see <code>IDialogConstants.*_ID</code> * constants for standard dialog button ids) * @param label * the label from the button * @param defaultButton * <code>true</code> if the button is to be the default button, * and <code>false</code> otherwise */ protected Button createButton(Composite parent, int id, String label, boolean defaultButton) { // increment the number of columns in the button bar ((GridLayout) parent.getLayout()).numColumns++; Button button = new Button(parent, SWT.PUSH); button.setFont(parent.getFont()); setButtonLayoutData(button); button.setData(Integer.valueOf(id)); button.setText(label); if (defaultButton) { Shell shell = parent.getShell(); if (shell != null) { shell.setDefaultButton(button); } button.setFocus(); } return button; } /** * Add the passed value to self's destination widget's history * * @param value * java.lang.String */ protected void addDestinationItem(String value) { destinationNameField.add(value); } @Override public void createControl(Composite parent) { initializeDialogUnits(parent); Composite composite = new Composite(parent, SWT.NULL); composite.setLayout(new GridLayout()); composite.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_FILL | GridData.HORIZONTAL_ALIGN_FILL)); createTransferArea(composite); setPreferenceTransfers(); restoreWidgetValues(); // updateWidgetEnablements(); // can not finish initially, but don't want to start with an error // message either if (!(validDestination() && validateOptionsGroup() && validateSourceGroup())) { setPageComplete(false); } setControl(composite); giveFocusToDestination(); Dialog.applyDialogFont(composite); } /** * @param composite */ protected abstract void createTransferArea(Composite composite); /** * Validate the destination group. * @return <code>true</code> if the group is valid. If * not set the error message and return <code>false</code>. */ protected boolean validateDestinationGroup() { if (!validDestination()) { currentMessage = getInvalidDestinationMessage(); return false; } return true; } /** * Return the message that indicates an invalid destination. * @return String */ abstract protected String getInvalidDestinationMessage(); private String getNoOptionsMessage() { return PreferencesMessages.WizardPreferencesPage_noOptionsSelected; } protected boolean validDestination() { File file = new File(getDestinationValue()); return !(file.getPath().length() <= 0 || file.isDirectory()); } protected void setPreferenceTransfers() { PreferenceTransferElement[] transfers = getTransfers(); viewer.setInput(transfers); } /* * return the PreferenceTransgerElements specified */ protected PreferenceTransferElement[] getTransfers() { if (transfers == null) { transfers = PreferenceTransferManager.getPreferenceTransfers(); } return transfers; } /** * @param composite */ protected void createTransfersList(Composite composite) { transferAllButton = new Button(composite, SWT.CHECK); transferAllButton.setText(getAllButtonText()); group = new Group(composite, SWT.NONE); GridData groupData = new GridData(GridData.FILL_BOTH); groupData.horizontalSpan = 2; groupData.horizontalIndent = LayoutConstants.getIndent(); Object compositeLayout = composite.getLayout(); if (compositeLayout instanceof GridLayout) { groupData.horizontalIndent -= ((GridLayout) compositeLayout).marginWidth; groupData.horizontalIndent -= ((GridLayout) compositeLayout).marginLeft; } group.setLayoutData(groupData); GridLayout layout = new GridLayout(); group.setLayout(layout); transfersTree = createFilteredTree(group); transfersTree.setLayoutData(new GridData(GridData.FILL_BOTH)); viewer = (CheckboxTreeViewer) transfersTree.getViewer(); viewer.setContentProvider(new PreferencesContentProvider()); viewer.setLabelProvider(new WorkbenchLabelProvider()); Label description = new Label(group, SWT.NONE); description.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); description.setText(PreferencesMessages.WizardPreferences_description); descText = new Text(group, SWT.V_SCROLL | SWT.READ_ONLY | SWT.BORDER | SWT.WRAP); GridData descriptionData = new GridData(GridData.FILL_BOTH); descriptionData.heightHint = convertHeightInCharsToPixels(3); descText.setLayoutData(descriptionData); transferAllButton.addSelectionListener(widgetSelectedAdapter(e -> { if (transferAllButton.getSelection()) { viewer.setAllChecked(false); } updateEnablement(); updatePageCompletion(); })); viewer.addSelectionChangedListener(event -> updateDescription()); viewer.addCheckStateListener(event -> { transferAllButton.setSelection(false); updateEnablement(); updatePageCompletion(); }); addSelectionButtons(group); } protected void updateDescription() { IStructuredSelection selection = viewer.getStructuredSelection(); String desc = ""; //$NON-NLS-1$ if (!selection.isEmpty()) { Object element = selection.getFirstElement(); if ((element instanceof PreferenceTransferElement)) { desc = ((PreferenceTransferElement) element).getDescription(); } } descText.setText(desc); } private FilteredTree createFilteredTree(Group group) { int style = SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER; FilteredTree transfersTree = new FilteredTree(group, style, new PatternFilter(), true) { @Override protected TreeViewer doCreateTreeViewer(Composite parent, int style) { return new CheckboxTreeViewer(parent, style); } }; return transfersTree; } protected abstract String getChooseButtonText(); protected abstract String getAllButtonText(); /** * Add the selection and deselection buttons to the composite. * * @param composite * org.eclipse.swt.widgets.Composite */ private void addSelectionButtons(Composite composite) { Font parentFont = composite.getFont(); buttonComposite = new Composite(composite, SWT.NONE); GridLayout layout = new GridLayout(); layout.numColumns = 2; buttonComposite.setLayout(layout); GridData data = new GridData(GridData.GRAB_HORIZONTAL); data.grabExcessHorizontalSpace = true; buttonComposite.setLayoutData(data); buttonComposite.setFont(parentFont); selectAllButton = new Button(buttonComposite, SWT.PUSH); selectAllButton.setText(PreferencesMessages.SelectionDialog_selectLabel); selectAllButton.setData(Integer.valueOf(IDialogConstants.SELECT_ALL_ID)); setButtonLayoutData(selectAllButton); SelectionListener listener = widgetSelectedAdapter(e -> { viewer.setAllChecked(true); updatePageCompletion(); }); selectAllButton.addSelectionListener(listener); selectAllButton.setFont(parentFont); deselectAllButton = new Button(buttonComposite, SWT.PUSH); deselectAllButton.setText(PreferencesMessages.SelectionDialog_deselectLabel); deselectAllButton.setData(Integer.valueOf(IDialogConstants.DESELECT_ALL_ID)); setButtonLayoutData(deselectAllButton); listener = widgetSelectedAdapter(e -> { viewer.setAllChecked(false); updatePageCompletion(); }); deselectAllButton.addSelectionListener(listener); deselectAllButton.setFont(parentFont); } /** * @param bool */ protected void setAllChecked(boolean bool) { transferAllButton.setSelection(false); } /** * Create the export destination specification widgets * * @param parent * org.eclipse.swt.widgets.Composite */ protected void createDestinationGroup(Composite parent) { // destination specification group Composite destinationSelectionGroup = new Composite(parent, SWT.NONE); GridLayout layout = new GridLayout(); layout.numColumns = 3; destinationSelectionGroup.setLayout(layout); destinationSelectionGroup.setLayoutData(new GridData( GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_FILL)); Label dest = new Label(destinationSelectionGroup, SWT.NONE); dest.setText(getDestinationLabel()); // destination name entry field destinationNameField = new Combo(destinationSelectionGroup, SWT.SINGLE | SWT.BORDER); destinationNameField.addListener(SWT.Modify, this); destinationNameField.addListener(SWT.Selection, this); GridData data = new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL); destinationNameField.setLayoutData(data); // destination browse button destinationBrowseButton = new Button(destinationSelectionGroup, SWT.PUSH); destinationBrowseButton .setText(PreferencesMessages.PreferencesExport_browse); setButtonLayoutData(destinationBrowseButton); destinationBrowseButton.addListener(SWT.Selection, this); new Label(parent, SWT.NONE); // vertical spacer } /** * Create the export options specification widgets. * * @param parent * org.eclipse.swt.widgets.Composite */ protected void createOptionsGroup(Composite parent) { // options group Composite optionsGroup = new Composite(parent, SWT.NONE); GridLayout layout = new GridLayout(); layout.marginHeight = 0; optionsGroup.setLayout(layout); optionsGroup.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL)); // overwrite... checkbox overwriteExistingFilesCheckbox = new Button(optionsGroup, SWT.CHECK | SWT.LEFT); overwriteExistingFilesCheckbox .setText(PreferencesMessages.ExportFile_overwriteExisting); } /** * Attempts to ensure that the specified directory exists on the local file * system. Answers a boolean indicating success. * * @return boolean * @param directory * java.io.File */ protected boolean ensureDirectoryExists(File directory) { if (!directory.exists()) { if (!queryYesNoQuestion(PreferencesMessages.PreferencesExport_createTargetDirectory)) { return false; } if (!directory.mkdirs()) { MessageDialog .open( MessageDialog.ERROR, getContainer().getShell(), PreferencesMessages.PreferencesExport_error, PreferencesMessages.PreferencesExport_directoryCreationError, SWT.SHEET); return false; } } return true; } /** * Displays a Yes/No question to the user with the specified message and * returns the user's response. * * @param message * the question to ask * @return <code>true</code> for Yes, and <code>false</code> for No */ protected boolean queryYesNoQuestion(String message) { MessageDialog dialog = new MessageDialog(getContainer().getShell(), PreferencesMessages.Question, (Image) null, message, MessageDialog.NONE, 0, IDialogConstants.YES_LABEL, IDialogConstants.NO_LABEL) { @Override protected int getShellStyle() { return super.getShellStyle() | SWT.SHEET; } }; // ensure yes is the default return dialog.open() == 0; } /** * If the target for export does not exist then attempt to create it. Answer * a boolean indicating whether the target exists (ie.- if it either * pre-existed or this method was able to create it) * * @return boolean */ protected boolean ensureTargetIsValid(File file) { if (file.exists()) { if (!getOverwriteExisting()) { String msg = NLS .bind( PreferencesMessages.WizardPreferencesExportPage1_overwrite, file.getAbsolutePath()); if (!queryYesNoQuestion(msg)) { return false; } } file.delete(); } else if (!file.isDirectory()) { File parent = file.getParentFile(); if (parent != null) { file.getParentFile().mkdirs(); } } return true; } protected void saveWidgetValues() { IDialogSettings settings = getDialogSettings(); if (settings != null) { String[] directoryNames = settings .getArray(STORE_DESTINATION_NAMES_ID); if (directoryNames == null) { directoryNames = new String[0]; } directoryNames = addToHistory(directoryNames, getDestinationValue()); settings.put(STORE_DESTINATION_NAMES_ID, directoryNames); String current = getDestinationValue(); if (current != null && !current.equals("")) { //$NON-NLS-1$ settings.put(STORE_DESTINATION_ID, current); } // options if (overwriteExistingFilesCheckbox != null) { settings.put(STORE_OVERWRITE_EXISTING_FILES_ID, overwriteExistingFilesCheckbox.getSelection()); } if (shouldSaveTransferAll()) { boolean transferAll = getTransferAll(); settings.put(TRANSFER_ALL_PREFERENCES_ID, transferAll); if (!transferAll) { Object[] elements = viewer.getCheckedElements(); String[] preferenceIds = new String[elements.length]; for (int i = 0; i < elements.length; i++) { PreferenceTransferElement element = (PreferenceTransferElement) elements[i]; preferenceIds[i] = element.getID(); } settings.put(TRANSFER_PREFERENCES_NAMES_ID, preferenceIds); } } } } /** * The Finish button was pressed. Try to do the required work now and answer * a boolean indicating success. If false is returned then the wizard will * not close. * * @return boolean */ public boolean finish() { // about to invoke the operation so save our state saveWidgetValues(); IPreferenceFilter[] transfers = null; if (getTransferAll()) { // export all transfers = new IPreferenceFilter[1]; // For export all create a preference filter that can export // all nodes of the Instance and Configuration scopes transfers[0] = new IPreferenceFilter() { @Override public String[] getScopes() { return new String[] { InstanceScope.SCOPE, ConfigurationScope.SCOPE }; } @Override public Map getMapping(String scope) { return null; } }; } else { transfers = getFilters(); } boolean success = transfer(transfers); // if it was a successful tranfer then store the name of the file to use // it on the next export if (success) { saveWidgetValues(); } return success; } /** * @return the preference transfer filters */ protected IPreferenceFilter[] getFilters() { IPreferenceFilter[] filters = null; PreferenceTransferElement[] transferElements; transferElements = getPreferenceTransferElements(); if (transferElements != null) { filters = new IPreferenceFilter[transferElements.length]; for (int j = 0; j < transferElements.length; j++) { PreferenceTransferElement element = transferElements[j]; try { filters[j] = element.getFilter(); } catch (CoreException e) { WorkbenchPlugin.log(e.getMessage(), e); } } } else { filters = new IPreferenceFilter[0]; } return filters; } /** * @return the list of transfer elements */ protected PreferenceTransferElement[] getPreferenceTransferElements() { Object[] checkedElements = viewer.getCheckedElements(); PreferenceTransferElement[] transferElements = new PreferenceTransferElement[checkedElements.length]; System.arraycopy(checkedElements, 0, transferElements, 0, checkedElements.length); return transferElements; } /** * @param transfers * @return boolean */ protected abstract boolean transfer(IPreferenceFilter[] transfers); /** * Check whether the internal state of the page is complete and update the * dialog */ public void setPageComplete() { boolean complete = true; if (!determinePageCompletion()) { complete = false; } super.setPageComplete(complete); } /** * Returns whether this page is complete. This determination is made based * upon the current contents of this page's controls. Subclasses wishing to * include their controls in this determination should override the hook * methods <code>validateSourceGroup</code> and/or * <code>validateOptionsGroup</code>. * * @return <code>true</code> if this page is complete, and * <code>false</code> if incomplete * @see #validateSourceGroup * @see #validateOptionsGroup */ protected boolean determinePageCompletion() { // validate groups in order of priority so error message is the most important one boolean complete = validateSourceGroup() && validateDestinationGroup() && validateOptionsGroup(); // Avoid draw flicker by not clearing the error // message unless all is valid. if (complete) { setErrorMessage(null); } else { setErrorMessage(currentMessage); } return complete; } /** * Returns whether this page's options group's controls currently all * contain valid values. * <p> * The <code>WizardPreferencesPage</code> implementation of this method * returns <code>true</code> if the button to transfer all preferences is * selected OR at least one of the individual items are checked. Subclasses * may reimplement this method. * </p> * * @return <code>true</code> indicating validity of all controls in the * options group */ protected boolean validateOptionsGroup() { boolean isValid = true; if (!getTransferAll()) { Object[] checkedElements = viewer.getCheckedElements(); if (checkedElements == null || checkedElements.length == 0) { currentMessage = getNoOptionsMessage(); isValid = false; } } return isValid; } /** * Returns whether this page's source specification controls currently all * contain valid values. * <p> * The <code>WizardDataTransferPage</code> implementation of this method * returns <code>true</code>. Subclasses may reimplement this hook * method. * </p> * * @return <code>true</code> indicating validity of all controls in the * source specification group */ protected boolean validateSourceGroup() { return true; } /** * Answer the string to display in self as the destination type * * @return java.lang.String */ protected abstract String getDestinationLabel(); /** * Answer the contents of self's destination specification widget * * @return java.lang.String */ protected String getDestinationValue() { return destinationNameField.getText().trim(); } /** * Set the current input focus to self's destination entry field */ protected void giveFocusToDestination() { destinationNameField.setFocus(); } /** * Open an appropriate destination browser so that the user can specify a * source to import from */ protected void handleDestinationBrowseButtonPressed() { FileDialog dialog = new FileDialog(getContainer().getShell(), getFileDialogStyle()); dialog.setText(getFileDialogTitle()); dialog.setFilterPath(getDestinationValue()); dialog.setFilterExtensions(new String[] { "*.epf" ,"*.*"}); //$NON-NLS-1$ //$NON-NLS-2$ String selectedFileName = dialog.open(); if (selectedFileName != null) { setDestinationValue(selectedFileName); } } protected abstract String getFileDialogTitle(); protected abstract int getFileDialogStyle(); /** * Handle all events and enablements for widgets in this page * * @param e * Event */ @Override public void handleEvent(Event e) { Widget source = e.widget; if (source == destinationBrowseButton) { handleDestinationBrowseButtonPressed(); } updatePageCompletion(); } /** * Determine if the page is complete and update the page appropriately. */ protected void updatePageCompletion() { boolean pageComplete = determinePageCompletion(); setPageComplete(pageComplete); if (pageComplete) { setMessage(null); } } /** * Adds an entry to a history, while taking care of duplicate history items * and excessively long histories. The assumption is made that all histories * should be of length <code>WizardDataTransferPage.COMBO_HISTORY_LENGTH</code>. * * @param history the current history * @param newEntry the entry to add to the history */ protected String[] addToHistory(String[] history, String newEntry) { java.util.ArrayList l = new java.util.ArrayList(Arrays.asList(history)); addToHistory(l, newEntry); String[] r = new String[l.size()]; l.toArray(r); return r; } /** * Adds an entry to a history, while taking care of duplicate history items * and excessively long histories. The assumption is made that all histories * should be of length <code>WizardDataTransferPage.COMBO_HISTORY_LENGTH</code>. * * @param history the current history * @param newEntry the entry to add to the history */ protected void addToHistory(List history, String newEntry) { history.remove(newEntry); history.add(0, newEntry); // since only one new item was added, we can be over the limit // by at most one item if (history.size() > COMBO_HISTORY_LENGTH) { history.remove(COMBO_HISTORY_LENGTH); } } /** * Hook method for restoring widget values to the values that they held last * time this wizard was used to completion. */ protected void restoreWidgetValues() { IDialogSettings settings = getDialogSettings(); if (shouldSaveTransferAll() && settings != null) { boolean transferAll; if (settings.get(TRANSFER_ALL_PREFERENCES_ID) == null) transferAll = true; else transferAll = settings .getBoolean(TRANSFER_ALL_PREFERENCES_ID); transferAllButton.setSelection(transferAll); if (!transferAll) { String[] preferenceIds = settings .getArray(TRANSFER_PREFERENCES_NAMES_ID); if (preferenceIds != null) { PreferenceTransferElement[] transfers = getTransfers(); for (PreferenceTransferElement transfer : transfers) { for (String preferenceId : preferenceIds) { if (transfer.getID().equals(preferenceId)) { viewer.setChecked(transfer, true); break; } } } } } } else { transferAllButton.setSelection(true); } updateEnablement(); if (settings != null) { String[] directoryNames = settings .getArray(STORE_DESTINATION_NAMES_ID); if (directoryNames != null) { // destination setDestinationValue(directoryNames[0]); for (String directoryName : directoryNames) { addDestinationItem(directoryName); } String current = settings.get(STORE_DESTINATION_ID); if (current != null) { setDestinationValue(current); } // options if (overwriteExistingFilesCheckbox != null) { overwriteExistingFilesCheckbox.setSelection(settings .getBoolean(STORE_OVERWRITE_EXISTING_FILES_ID)); } } } } protected abstract boolean shouldSaveTransferAll(); private boolean getOverwriteExisting() { return overwriteExistingFilesCheckbox.getSelection(); } private boolean getTransferAll() { return transferAllButton.getSelection(); } /** * Set the contents of self's destination specification widget to the passed * value * * @param value * java.lang.String */ protected void setDestinationValue(String value) { destinationNameField.setText(value); } @Override public void dispose() { super.dispose(); transfers = null; } protected boolean allowNewContainerName() { return true; } /** * The <code>WizardDataTransfer</code> implementation of this * <code>IOverwriteQuery</code> method asks the user whether the existing * resource at the given path should be overwritten. * * @param pathString * @return the user's reply: one of <code>"YES"</code>, <code>"NO"</code>, * <code>"ALL"</code>, or <code>"CANCEL"</code> */ @Override public String queryOverwrite(String pathString) { Path path = new Path(pathString); String messageString; // Break the message up if there is a file name and a directory // and there are at least 2 segments. if (path.getFileExtension() == null || path.segmentCount() < 2) { messageString = NLS.bind( PreferencesMessages.WizardDataTransfer_existsQuestion, pathString); } else { messageString = NLS .bind( PreferencesMessages.WizardDataTransfer_overwriteNameAndPathQuestion, path.lastSegment(), path.removeLastSegments(1) .toOSString()); } final MessageDialog dialog = new MessageDialog(getContainer().getShell(), PreferencesMessages.Question, null, messageString, MessageDialog.QUESTION, 0, IDialogConstants.YES_LABEL, IDialogConstants.YES_TO_ALL_LABEL, IDialogConstants.NO_LABEL, IDialogConstants.NO_TO_ALL_LABEL, IDialogConstants.CANCEL_LABEL) { @Override protected int getShellStyle() { return super.getShellStyle() | SWT.SHEET; } }; String[] response = new String[] { YES, ALL, NO, NO_ALL, CANCEL }; // run in syncExec because callback is from an operation, // which is probably not running in the UI thread. getControl().getDisplay().syncExec(() -> dialog.open()); return dialog.getReturnCode() < 0 ? CANCEL : response[dialog .getReturnCode()]; } private void updateEnablement() { boolean transferAll = getTransferAll(); selectAllButton.setEnabled(!transferAll); deselectAllButton.setEnabled(!transferAll); } }